package com.yuhong.springbootinit.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yuhong.springbootinit.common.ErrorCode;
import com.yuhong.springbootinit.constant.CommonConstant;
import com.yuhong.springbootinit.exception.BusinessException;
import com.yuhong.springbootinit.exception.ThrowUtils;
import com.yuhong.springbootinit.mapper.*;
import com.yuhong.springbootinit.model.dto.analysis.PositionLocationResponse;
import com.yuhong.springbootinit.model.dto.analysis.PositionSalaryResponse;
import com.yuhong.springbootinit.model.dto.analysis.PositionStatusResponse;
import com.yuhong.springbootinit.model.dto.analysis.PositionTagResponse;
import com.yuhong.springbootinit.model.dto.position.PositionApplicationSimpleDTO;
import com.yuhong.springbootinit.model.entity.Applicant;
import com.yuhong.springbootinit.model.entity.CompanyPosition;
import com.yuhong.springbootinit.model.entity.CompanyUser;
import com.yuhong.springbootinit.model.entity.Position;
import com.yuhong.springbootinit.model.entity.Application;

import com.yuhong.springbootinit.model.dto.position.PositionQueryRequest;

import com.yuhong.springbootinit.model.vo.PositionVO;
import com.yuhong.springbootinit.service.ApplicationService;
import com.yuhong.springbootinit.service.PositionService;
import com.yuhong.springbootinit.service.UserService;
import com.yuhong.springbootinit.utils.SqlUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

import static com.yuhong.springbootinit.model.enums.PositionStatusEnum.PUBLISHED;

/**
* @author 10467
* @description 针对表【position】的数据库操作Service实现
* @createDate 2025-02-22 13:52:10
*/
@Service
public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements PositionService{


    @Resource
    private UserService userService;

    @Resource
    private PositionMapper positionMapper;


    @Resource
    private ApplicantMapper applicantMapper;


    @Resource
    private CompanyPositionMapper companyPositionMapper;

    @Resource
    private CompanyUserMapper companyUserMapper;

    @Resource
    private ApplicationService applicationService;

    @Override
    public void validPosition(Position position, boolean add) {
        if (position == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        String title = position.getTitle();
        Integer salary = position.getSalary();
        String location = position.getLocation();
        String gen = position.getGen();
        String bg = position.getBg();
        String requirement = position.getRequirement();
        String description = position.getDescription();
        Date startDate = position.getStartDate();
        Date endDate = position.getEndDate();

        // 创建时，参数不能为空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(title, requirement, location,gen,bg,description), ErrorCode.PARAMS_ERROR);
        }
        // 有参数则校验
        if (StringUtils.isNotBlank(title) && title.length() > 80) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "标题过长");
        }
        if (StringUtils.isNotBlank(requirement) && requirement.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长");
        }
        if (StringUtils.isNotBlank(description) && description.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "描述过长");
        }
        if (StringUtils.isNotBlank(gen) && gen.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "描述过长");
        }
        if (StringUtils.isNotBlank(bg) && bg.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "描述过长");
        }
        if(salary < 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "非法参数");
        }
    }

    @Override
    public PositionVO getPositionVO(Position position, HttpServletRequest request) throws JsonProcessingException {
        PositionVO positionVO = PositionVO.objToVo(position);

//        BeanUtil.copyProperties(PositionVO.class,position);
//
//        long postId = position.getId();
//        // 1. 关联查询用户信息
//        Long userId = position.getUserId();
//        User user = null;
//        if (userId != null && userId > 0) {
//            user = userService.getById(userId);
//        }
//        UserVO userVO = userService.getUserVO(user);
//        positionVO.setUser(userVO);
//        // 2. 已登录，获取用户点赞、收藏状态
//        User loginUser = userService.getLoginUserPermitNull(request);
//        if (loginUser != null) {
//            // 获取点赞
//            QueryWrapper<PostThumb> postThumbQueryWrapper = new QueryWrapper<>();
//            postThumbQueryWrapper.in("postId", postId);
//            postThumbQueryWrapper.eq("userId", loginUser.getId());
//            PostThumb postThumb = postThumbMapper.selectOne(postThumbQueryWrapper);
//            postVO.setHasThumb(postThumb != null);
//            // 获取收藏
//            QueryWrapper<PostFavour> postFavourQueryWrapper = new QueryWrapper<>();
//            postFavourQueryWrapper.in("postId", postId);
//            postFavourQueryWrapper.eq("userId", loginUser.getId());
//            PostFavour postFavour = postFavourMapper.selectOne(postFavourQueryWrapper);
//            postVO.setHasFavour(postFavour != null);
//        }
        return positionVO;
    }

    @Override
    public Page<PositionVO> getPositionVOPage(Page<Position> positionPage, HttpServletRequest request) {
        List<Position> postList = positionPage.getRecords();
        Page<PositionVO> positionVOPage = new Page<>(positionPage.getCurrent(), positionPage.getSize(), positionPage.getTotal());
        if (CollUtil.isEmpty(postList)) {
            return positionVOPage;
        }

        List<PositionVO> positionVOS = BeanUtil.copyToList(postList, PositionVO.class);
        positionVOPage.setRecords(positionVOS);

//        // 1. 关联查询用户信息
//        Set<Long> userIdSet = postList.stream().map(Position::getUserId).collect(Collectors.toSet());
//        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
//                .collect(Collectors.groupingBy(User::getId));
//        // 2. 已登录，获取用户点赞、收藏状态
//        Map<Long, Boolean> postIdHasThumbMap = new HashMap<>();
//        Map<Long, Boolean> postIdHasFavourMap = new HashMap<>();
//        User loginUser = userService.getLoginUserPermitNull(request);
//        if (loginUser != null) {
//            Set<Long> postIdSet = postList.stream().map(Post::getId).collect(Collectors.toSet());
//            loginUser = userService.getLoginUser(request);
//            // 获取点赞
//            QueryWrapper<PostThumb> postThumbQueryWrapper = new QueryWrapper<>();
//            postThumbQueryWrapper.in("postId", postIdSet);
//            postThumbQueryWrapper.eq("userId", loginUser.getId());
//            List<PostThumb> postPostThumbList = postThumbMapper.selectList(postThumbQueryWrapper);
//            postPostThumbList.forEach(postPostThumb -> postIdHasThumbMap.put(postPostThumb.getPostId(), true));
//            // 获取收藏
//            QueryWrapper<PostFavour> postFavourQueryWrapper = new QueryWrapper<>();
//            postFavourQueryWrapper.in("postId", postIdSet);
//            postFavourQueryWrapper.eq("userId", loginUser.getId());
//            List<PostFavour> postFavourList = postFavourMapper.selectList(postFavourQueryWrapper);
//            postFavourList.forEach(postFavour -> postIdHasFavourMap.put(postFavour.getPostId(), true));
//        }
        // 填充信息
//        List<PostVO> postVOList = postList.stream().map(post -> {
//            PostVO postVO = PostVO.objToVo(post);
//            Long userId = post.getUserId();
//            User user = null;
//            if (userIdUserListMap.containsKey(userId)) {
//                user = userIdUserListMap.get(userId).get(0);
//            }
//            postVO.setUser(userService.getUserVO(user));
//            postVO.setHasThumb(postIdHasThumbMap.getOrDefault(post.getId(), false));
//            postVO.setHasFavour(postIdHasFavourMap.getOrDefault(post.getId(), false));
//            return postVO;
//        }).collect(Collectors.toList());
//        postVOPage.setRecords(postVOList);
        return positionVOPage;
    }

    @Override
    public QueryWrapper<Position> getQueryWrapper(PositionQueryRequest positionQueryRequest) {
        QueryWrapper<Position> queryWrapper = new QueryWrapper<>();
        if (positionQueryRequest == null) {
            return queryWrapper;
        }

        Long id = positionQueryRequest.getId();
        String positionId = positionQueryRequest.getPositionId();
        String title = positionQueryRequest.getTitle();
        String location = positionQueryRequest.getLocation();
        Integer status = positionQueryRequest.getStatus();
        String userAccount = positionQueryRequest.getUserId();
        Date startDate = positionQueryRequest.getStartDate();
        Date endDate = positionQueryRequest.getEndDate();

        String sortField = positionQueryRequest.getSortField();
        String sortOrder = positionQueryRequest.getSortOrder();
        List<String> tags = positionQueryRequest.getTags();

        // 拼接查询条件
        if (StringUtils.isNotBlank(location)) {
//            queryWrapper.and(qw -> qw.like("title", location).or().like("content", location));
            queryWrapper.like("location",location);
        }
        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
//        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
        if (CollUtil.isNotEmpty(tags)) {
            for (String tag : tags) {
                queryWrapper.like("tags", "\"" + tag + "\"");
            }
        }
//        queryWrapper.ne(ObjectUtils.isNotEmpty(notId), "id", notId);
        // TODO: 2025/4/5 职位列表：我发布的 我公司的
        queryWrapper.eq(ObjectUtils.isNotEmpty(positionId), "position_id", positionId);

        queryWrapper.eq(ObjectUtils.isNotEmpty(status), "status", status);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userAccount), "user_id", userAccount);
        queryWrapper.lambda().ge(ObjectUtils.isNotEmpty(startDate),Position::getStartDate, startDate);
        queryWrapper.lambda().le(ObjectUtils.isNotEmpty(endDate),Position::getEndDate, endDate);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    @Override
    public Position updatePositionStatus(Long id) {
        QueryWrapper<Position> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Position::getId, id);
        Position position = positionMapper.selectOne(queryWrapper);
        position.setStatus(PUBLISHED.getCode());
        int success = positionMapper.updateById(position);

        return position;
    }

    @Override
    public PositionLocationResponse getLocationRatios() {

        // 查询所有不同的location及其数量
        QueryWrapper<Position> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("location", "COUNT(*) as count").groupBy("location");
        List<Map<String, Object>> locationCounts = positionMapper.selectMaps(queryWrapper);

        // 计算总职位数
        int totalPositions = 0;
        for (Map<String, Object> map : locationCounts) {
            totalPositions += Integer.parseInt(map.get("count").toString());
        }

        QueryWrapper<Applicant> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.select("location", "COUNT(*) as count").groupBy("location");
        List<Map<String, Object>> applicantCounts = applicantMapper.selectMaps(queryWrapper1);

        // 计算总用户数
        int totalAccounts = applicantCounts.stream()
                .filter(map -> map.get("count") != null)  // 过滤null值
                .mapToInt(map -> Integer.parseInt(map.get("count").toString()))
                .sum();

        // 创建并填充LocationRatio对象列表
//        List<PositionLocationRatioDTO> ratios = new ArrayList<>();
//        for (Map<String, Object> map : locationCounts) {
//            PositionLocationRatioDTO ratio = new PositionLocationRatioDTO();
//            ratio.setLocation((String) map.get("location"));
//            ratio.setRate(Double.parseDouble(map.get("count").toString()) / totalPositions);
//            ratios.add(ratio);
//        }

        PositionLocationResponse positionLocationResponse = new PositionLocationResponse();
        positionLocationResponse.setPositionDataList(locationCounts);
        positionLocationResponse.setTotalPosition(totalPositions);
        positionLocationResponse.setPostNum(locationCounts.size());
        positionLocationResponse.setApplicantDataList(applicantCounts);
        positionLocationResponse.setApplicantNum(applicantCounts.size());
        positionLocationResponse.setTotalApplicant(totalAccounts);

        return positionLocationResponse;

    }

    @Override
    public PositionStatusResponse getStatusRatios() {
        QueryWrapper<Position> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("status", "COUNT(*) as count").groupBy("status");
        List<Map<String, Object>> statusCounts = positionMapper.selectMaps(queryWrapper);

        // 计算总职位数
        int totalPositions = statusCounts.stream()
                .mapToInt(map -> Integer.parseInt(map.get("count").toString()))
                .sum();

        // 创建结果列表
//        List<PositionStatusRatioDTO> ratios = new ArrayList<>();
//        for (PositionStatusEnum status : PositionStatusEnum.values()) {
//            PositionStatusRatioDTO dto = new PositionStatusRatioDTO();
//            dto.setStatus(status.getName());
//
//            int count = findCountByStatusCode(statusCounts, status.getCode());
//            double ratio = totalPositions > 0 ? ((double) count / totalPositions) : 0;
//            dto.setRate(ratio);
//            ratios.add(dto);
//        }

        PositionStatusResponse positionStatusResponse = new PositionStatusResponse();
        positionStatusResponse.setDataList(statusCounts);
        positionStatusResponse.setTotal(totalPositions);
        positionStatusResponse.setPostNum(statusCounts.size());

        return positionStatusResponse;

    }

    @Override
    public PositionSalaryResponse getSalaryRatios() {
        QueryWrapper<Position> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("salary", "COUNT(*) as count").groupBy("salary");
        List<Map<String, Object>> salaryCounts = positionMapper.selectMaps(queryWrapper);

        // 计算总职位数
        int totalPositions = salaryCounts.stream()
                .mapToInt(map -> Integer.parseInt(map.get("count").toString()))
                .sum();

        // 创建结果列表
//        List<PositionSalaryRatioDTO> ratios = new ArrayList<>();
//        for (Map<String, Object> map : salaryCounts) {
//            PositionSalaryRatioDTO dto = new PositionSalaryRatioDTO();
//            dto.setSalary(Integer.parseInt(map.get("salary").toString()));
//
//            int count = Integer.parseInt(map.get("count").toString());
//            double ratio = totalPositions > 0 ? ((double) count / totalPositions) : 0;
//            dto.setRate(ratio);
//            ratios.add(dto);
//        }
        PositionSalaryResponse positionSalaryResponse = new PositionSalaryResponse();
        positionSalaryResponse.setDataList(salaryCounts);
        positionSalaryResponse.setTotal(totalPositions);
        positionSalaryResponse.setPostNum(salaryCounts.size());

        return positionSalaryResponse;
    }

    @Override
    public PositionTagResponse getTagRatios() throws JsonProcessingException {
        QueryWrapper<Position> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("tags");
        List<Position> positions = positionMapper.selectList(queryWrapper);

        Map<String, Integer> tagCounts = new HashMap<>();
        int totalPositions = 0;

        for (Position position : positions) {
            ObjectMapper objectMapper = new ObjectMapper();
            List<String> tagList = objectMapper.readValue(position.getTags(),objectMapper.getTypeFactory().constructCollectionType(List.class, String.class));
            if (tagList != null) {
                for (String tag : tagList) {
                    tagCounts.put(tag, tagCounts.getOrDefault(tag, 0) + 1);
                    totalPositions++;
                }
            }
        }
        PositionTagResponse tagResponse = new PositionTagResponse();
        tagResponse.setDataList(tagCounts);
        tagResponse.setTotal(totalPositions);

        return tagResponse;
    }

    @Override
    public List<Position> getPositionListByCompanyId(String companyId) {
        // 1. 查询中间表中该公司对应的所有职位 ID
        QueryWrapper<CompanyPosition> wrapper = new QueryWrapper<>();
        wrapper.eq("company_id", companyId);
        List<CompanyPosition> relationList = companyPositionMapper.selectList(wrapper);

        if (relationList.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 提取职位 ID 列表
        List<String> positionIds = relationList.stream()
                .map(CompanyPosition::getPositionId)
                .collect(Collectors.toList());

        // 3. 查询职位信息
        return this.list(new QueryWrapper<Position>().in("position_id", positionIds));
    }

    private int findCountByStatusCode(List<Map<String, Object>> statusCounts, int statusCode) {
        for (Map<String, Object> map : statusCounts) {
            if (map.get("status").equals(statusCode)) {
                return Integer.parseInt(map.get("count").toString());
            }
        }
        return 0;
    }

    @Override
    public List<Position> getPositionsByUserId(String userId) {
        // 查找该 userId 所在的公司列表
        List<String> companyIds = companyUserMapper.selectList(
                new LambdaQueryWrapper<CompanyUser>().eq(CompanyUser::getUserId, userId)
        ).stream().map(CompanyUser::getCompanyId).distinct().collect(Collectors.toList());

        if (companyIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 根据公司id查询职位id列表
        List<String> positionIds = companyPositionMapper.selectList(
                new LambdaQueryWrapper<CompanyPosition>().in(CompanyPosition::getCompanyId, companyIds)
        ).stream().map(CompanyPosition::getPositionId).distinct().collect(Collectors.toList());

        if (positionIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 查询职位信息
        return positionMapper.selectList(
                new LambdaQueryWrapper<Position>().in(Position::getPositionId, positionIds)
        );
    }

    @Override
    public List<PositionApplicationSimpleDTO> getSimpleApplicationCountByPosition(String userId) {
        // 1. 查询该用户创建的所有职位
        List<Position> positions = this.lambdaQuery()
                .eq(Position::getUserId, userId)
                .select(Position::getPositionId, Position::getTitle, Position::getLocation, Position::getGen, Position::getSalary)
                .list();

        if (positions.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 获取这些职位的 positionId 列表
        List<String> positionIds = positions.stream()
                .map(Position::getPositionId)
                .collect(Collectors.toList());

        // 3. 查询每个 positionId 的申请数量
        List<Application> applications = applicationService.lambdaQuery()
                .in(Application::getPositionId, positionIds)
                .select(Application::getPositionId)
                .list();

        // 4. 统计每个 positionId 的数量
        Map<String, Long> countMap = applications.stream()
                .collect(Collectors.groupingBy(Application::getPositionId, Collectors.counting()));

        // 5. 组装返回结果
        return positions.stream()
                .map(pos -> new PositionApplicationSimpleDTO(
                        pos.getPositionId(),
                        pos.getTitle(),
                        pos.getLocation(),
                        pos.getGen(),
                        pos.getSalary(),
                        countMap.getOrDefault(pos.getPositionId(), 0L).intValue()

                ))
                .collect(Collectors.toList());
    }


}




